home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 23
/
AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso
/
Updates
/
Datatypes
/
RGFX-DT
/
Source
/
savergfx.c
< prev
Wrap
C/C++ Source or Header
|
1999-11-14
|
6KB
|
230 lines
#include <clib/alib_protos.h>
#include <clib/cybergraphics_protos.h>
#include <clib/datatypes_protos.h>
#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <clib/iffparse_protos.h>
#include <clib/intuition_protos.h>
#include <clib/xpkmaster_protos.h>
#include <datatypes/pictureclass.h>
#include <exec/memory.h>
//#include <libraries/rgfx.h>
#include "class.h"
#include "rgfx.h"
extern Library *CyberGfxBase;
void ReadPrefs(Data *data);
static BOOL PutRGHD(IFFHandle *iff,RGHD *rh)
{
BOOL ret=0;
if(!PushChunk(iff,0,ID_RGHD,sizeof(RGHD)))
{
if(WriteChunkRecords(iff,rh,sizeof(RGHD),1)==1)
{
if(!PopChunk(iff)) ret=1;
}
}
return ret;
}
static BOOL PutRCOL(Object *obj,IFFHandle *iff)
{
BOOL ret=0;
if(!PushChunk(iff,0,ID_RCOL,sizeof(RCOL)))
{
RCOL *rc;
if(rc=(RCOL *)AllocVec(sizeof(RCOL),MEMF_CLEAR))
{
ULONG i,n,*cr;
GetDTAttrs(obj,PDTA_NumColors,&n,PDTA_CRegs,&cr,TAG_END);
for(i=0;i<n;i++)
{
UWORD j;
for(j=0;j<3;j++) rc->rcol_Colors[i][j]=*(cr++)>>24;
}
if(WriteChunkRecords(iff,rc,sizeof(RCOL),1)==1)
{
if(!PopChunk(iff)) ret=1;
}
FreeVec(rc);
}
}
return ret;
}
static BOOL PutRSCM(Object *obj,IFFHandle *iff,RGHD *rh)
{
BOOL ret=0;
if(!PushChunk(iff,0,ID_RSCM,sizeof(RSCM)))
{
ULONG mode;
RSCM rs={INVALID_ID,INVALID_ID,INVALID_ID};
GetDTAttrs(obj,PDTA_ModeID,&mode,TAG_END);
if(CyberGfxBase&&IsCyberModeID(mode))
{
rs.rscm_CGfx=mode;
if(rh->rgfx_Depth<=8) rs.rscm_AGA=BestModeID(
BIDTAG_NominalWidth,rh->rgfx_PageWidth,BIDTAG_NominalHeight,rh->rgfx_PageHeight,
BIDTAG_DesiredWidth,rh->rgfx_Width,BIDTAG_DesiredHeight,rh->rgfx_Height,
BIDTAG_Depth,rh->rgfx_Depth,BIDTAG_MonitorID,DEFAULT_MONITOR_ID,
BIDTAG_DIPFMustNotHave,DIPF_IS_DUALPF|DIPF_IS_PF2PRI|DIPF_IS_HAM|DIPF_IS_EXTRAHALFBRITE,TAG_END);
}
else
{
rs.rscm_AGA=mode;
if(!(mode&(HAM_KEY|EXTRAHALFBRITE_KEY|LORESDPF_KEY)))
{
if(CyberGfxBase) rs.rscm_CGfx=BestCModeIDTags(CYBRBIDTG_NominalWidth,rh->rgfx_Width,CYBRBIDTG_NominalHeight,rh->rgfx_Height,CYBRBIDTG_Depth,rh->rgfx_Depth,TAG_END);
}
}
if(WriteChunkRecords(iff,&rs,sizeof(RSCM),1)==1)
{
if(!PopChunk(iff)) ret=1;
}
}
return ret;
}
static BOOL WriteChunky_XPK(Object *obj,IFFHandle *iff,RGHD *rh,BitMap *bm,Data *data)
{
BOOL ret=0;
ULONG len=rh->rgfx_Width*rh->rgfx_Height;
UBYTE *mem;
if(mem=(UBYTE *)AllocVec(len,0))
{
UBYTE *pix;
if(pix=(UBYTE *)AllocVec(((rh->rgfx_Width+16)>>4)<<4,0))
{
BitMap *tbm;
if(tbm=AllocBitMap(rh->rgfx_Width,1,rh->rgfx_Depth,0,bm))
{
ULONG y,xpklen,outlen;
UBYTE *xpk=mem;
RastPort rp,trp;
InitRastPort(&rp);
InitRastPort(&trp);
rp.BitMap=bm;
trp.BitMap=tbm;
for(y=0;y<rh->rgfx_Height;y++,xpk+=rh->rgfx_Width)
{
ReadPixelLine8(&rp,0,y,rh->rgfx_Width,pix,&trp);
CopyMem(pix,xpk,rh->rgfx_Width);
}
if(!XpkPackTags(XPK_InBuf,mem,XPK_InLen,len,XPK_GetOutBuf,&xpk,XPK_GetOutBufLen,&xpklen,XPK_GetOutLen,&outlen,XPK_PackMethod,data->xpk,XPK_PackMode,data->xpkmode,XPK_Password,data->password,TAG_END))
{
if(WriteChunkRecords(iff,xpk,outlen,1)==1) ret=1;
FreeMem(xpk,xpklen);
}
FreeBitMap(tbm);
}
FreeVec(pix);
}
FreeVec(mem);
}
return ret;
}
static BOOL Write24_XPK(Object *obj,IFFHandle *iff,RGHD *rh,Data *data)
{
BOOL ret=0;
UBYTE *pix;
ULONG len=rh->rgfx_BytesPerLine*rh->rgfx_Height;
if(pix=(UBYTE *)AllocVec(len,0))
{
ULONG xpklen,outlen;
UBYTE *xpk;
DoMethod(obj,PDTM_READPIXELARRAY,pix,RECTFMT_RGB,rh->rgfx_BytesPerLine,0,0,rh->rgfx_Width,rh->rgfx_Height);
if(!XpkPackTags(XPK_InBuf,pix,XPK_InLen,len,XPK_GetOutBuf,&xpk,XPK_GetOutBufLen,&xpklen,XPK_GetOutLen,&outlen,XPK_PackMethod,data->xpk,XPK_PackMode,data->xpkmode,XPK_Password,data->password,TAG_END))
{
if(WriteChunkRecords(iff,xpk,outlen,1)==1) ret=1;
FreeMem(xpk,xpklen);
}
FreeVec(pix);
}
return ret;
}
static BOOL PutBODY(IClass *cl,Object *obj,IFFHandle *iff,RGHD *rh)
{
BOOL ret=0;
if(!PushChunk(iff,0,ID_RBOD,IFFSIZE_UNKNOWN))
{
BOOL wok=0;
BitMap *bm;
Data *data=(Data *)INST_DATA(cl,obj);
ReadPrefs(data);
GetDTAttrs(obj,PDTA_BitMap,&bm,TAG_END);
if(rh->rgfx_Depth>8) wok=Write24_XPK(obj,iff,rh,data);
else wok=WriteChunky_XPK(obj,iff,rh,bm,data);
if(wok)
{
if(!PopChunk(iff)) ret=1;
}
}
return ret;
}
ULONG SaveRGFX(IClass *cl,Object *obj,dtWrite *msg)
{
ULONG retval=0;
IFFHandle *iff;
SignalSemaphore *lock=((DTSpecialInfo *)((Gadget *)obj)->SpecialInfo);
ObtainSemaphoreShared(lock);
if(iff=AllocIFF())
{
iff->iff_Stream=msg->dtw_FileHandle;
InitIFFasDOS(iff);
if(!OpenIFF(iff,IFFF_WRITE))
{
if(!PushChunk(iff,ID_RGFX,ID_FORM,IFFSIZE_UNKNOWN))
{
BOOL ok=0;
BitMapHeader *bh;
RGHD rh;
GetDTAttrs(obj,PDTA_BitMapHeader,&bh,TAG_END);
rh.rgfx_LeftEdge=bh->bmh_Left;
rh.rgfx_TopEdge=bh->bmh_Top;
rh.rgfx_Width=bh->bmh_Width;
rh.rgfx_Height=bh->bmh_Height;
rh.rgfx_PageWidth=bh->bmh_PageWidth;
rh.rgfx_PageHeight=bh->bmh_PageHeight;
rh.rgfx_Depth=bh->bmh_Depth;
if(rh.rgfx_Depth<=8)
{
rh.rgfx_PixelBits=8;
rh.rgfx_BytesPerLine=rh.rgfx_Width;
rh.rgfx_BitMapType=RMBT_BYTECHUNKY8;
}
else
{
rh.rgfx_PixelBits=24;
rh.rgfx_BytesPerLine=rh.rgfx_Width*3;
rh.rgfx_BitMapType=RMBT_3BYTERGB24;
}
rh.rgfx_Compression=RCMT_XPK;
rh.rgfx_XAspect=bh->bmh_XAspect;
rh.rgfx_YAspect=bh->bmh_YAspect;
if(PutRGHD(iff,&rh))
{
if(bh->bmh_Depth>8||PutRCOL(obj,iff))
{
if(PutRSCM(obj,iff,&rh)) ok=PutBODY(cl,obj,iff,&rh);
}
}
if(ok)
{
if(PopChunk(iff)) ok=0;
else retval=1;
}
}
CloseIFF(iff);
}
FreeIFF(iff);
}
ReleaseSemaphore(lock);
return retval;
}